{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 429 ms\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "import common\n",
    "import numpy as np\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "train_set = common.get_train_set()\n",
    "tfidf = TfidfVectorizer(min_df=1, max_df=0.5, stop_words=['停词'], max_features=1000000)\n",
    "%time tfidf_array = tfidf.fit_transform(raw_documents=train_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 1.74 s\n"
     ]
    }
   ],
   "source": [
    "from sklearn.cluster import KMeans, MiniBatchKMeans\n",
    "def get_kmeans_model(tfidf_array, k, use_mini_batch=False):\n",
    "    if use_mini_batch:\n",
    "        km = MiniBatchKMeans(n_clusters=k, init='k-means++', n_init=1,\n",
    "                             init_size=1000, batch_size=100, max_iter=1000, verbose=False)\n",
    "    else:\n",
    "        km = KMeans(n_clusters=k, init='k-means++', max_iter=100, n_init=1,\n",
    "                    verbose=False)\n",
    "    km.fit(tfidf_array)\n",
    "    return km\n",
    "# k为质心数量\n",
    "k = 10\n",
    "%time km = get_kmeans_model(tfidf_array=tfidf_array, k=k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.        , 0.        , 0.        , ..., 0.        , 0.        ,\n",
       "        0.        ],\n",
       "       [0.        , 0.        , 0.        , ..., 0.        , 0.        ,\n",
       "        0.        ],\n",
       "       [0.        , 0.00094732, 0.        , ..., 0.        , 0.        ,\n",
       "        0.        ],\n",
       "       ...,\n",
       "       [0.        , 0.        , 0.        , ..., 0.        , 0.        ,\n",
       "        0.        ],\n",
       "       [0.        , 0.        , 0.        , ..., 0.        , 0.        ,\n",
       "        0.        ],\n",
       "       [0.        , 0.        , 0.        , ..., 0.00084582, 0.        ,\n",
       "        0.        ]])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 中心点向量\n",
    "km.cluster_centers_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5 5 5 5 5 0 1 5 5 4 2 5 3 5 5 3 5 5 5 2 4 8 4 5 5 4 3 1 4 1 5 3 7 7 4 2 5\n",
      " 5 5 9 6 5 2 1 5 6 4 6 0 1 5 3 6 5 4 2 1 1 5 2 6 5 6 5 5 5 3 5 5 4 6 4 4 6\n",
      " 5 4 5 5 1 4 5 3 4 5 5 5 5 3 5 6 1 5 6 5 7 1 5 5 4 0 5 6 5 5 4 5 5 5 6 3 6\n",
      " 5 3 5 7 5 4 5 4 7 1 5 5 2 4 4 4 5 3 4 4 4 7 2 2 4 6 5 5 1 4 7 5 3 4 4 5 4\n",
      " 2 2 5 5 5 4 4 5 5 6 3 6 5 3 2 7 1 5 3 4 5 5 9 5 5 3 6 6 2 6 4 4 5 3 2 4 4\n",
      " 4 4 1 5 4 6 4 5 5 5 4 9 4 5 5 5 2 4 0 3 8 5 4 6 5 5 5 5 3 5 5 2 3 3 4 4 6\n",
      " 4 6 4 5 5 5 4 3 5 5 9 4 4 5 5 3 3 4 0 3 4 5 3 2 0 7 5 3 7 5 4 4 6 4 3 7 5\n",
      " 5 5 5 5 3 1 4 7 5 9 4 4 5 4 1 4 4 4 4 4 7 4 5 1 7 4 7 5 4 3 4 7 8 5 5 5 5\n",
      " 3 4 4 5 5 4 5 5 4 4 4 3 5 5 3 6 6 4 5 7 5 6 7 7 5 7 4 5 5 5 7 5 4 2 0 5 5\n",
      " 4 3 8 6 5 4 5 5 2 5 5 5 7 7 7 4 2 5 5 8 3 4 4 1 3 3 7 8 4 5 5 5 4 8 4 5 5\n",
      " 4 5 4 5 2 9 9 9 5 0 9 9 9 5 5 4 2 3 4 4 1 9 4 4 5 3 4 3 0 7 4 4 1 5 3 4 5\n",
      " 3 4 8 5 7 5 2 5 5 5 3 5 3 5 4 9 9 5 5 8 5 4 9 9 9 2 9 9 5 9 9 9 9 3 5 9 3\n",
      " 1 4 5 4 5 5 5 3 5 1 6 6 4 5 4 4 4 5 3 7 4 4 4 4 4 4 5 7 3 1 5 9 5 3 5 5 7\n",
      " 5 3 4 5 6 5 5 3 4 7 4 3 8 2 4 3 5 4 8 5 3 4 4 3 3 5 5 3 5 4 5 5 5 6 4 2 1\n",
      " 1 3 3 4 4 4 6 2 5 4 4 5 3 5 9 5 4 3 3 6 5 9 4 5 0 4 6 3 5 4 3 5 3 1 7 3 5\n",
      " 6 4 4 1 5 7 3 3 6 2 5 5 5 9 3 8 4 7 4 1 2 5 5 8 7 5 7 2 5 4 2 5 3 1 5 2 7\n",
      " 4 5 2 4 3 7 2 6 1 1 8 5 3 5 2 1 4 8 4 5 5 1 6 3 3 5 5 4 4 1 7 4 3 5 4 3 4\n",
      " 7 4 4 4 3 3 5 5 4 4 4 4 2 2 3 4 4 4 4 4 6 2 5 5 5 4 4 5 3 6 1 4 5 4 5 6 4\n",
      " 4 3 4 3 1 9 5 4 4 7 3 5 3 5 3 4 3 8 1 4 5 4 5 3 7 5 5 5 3 5 8 4 4 4 3 4 5\n",
      " 1 6 3 2 5 6 6 3 5 2 5 5 2 7 5 6 4 3 4 1 5 5 6 5 5 5 7 7 3 4 4 5 5 3 4 5 7\n",
      " 5 2 3 1 5 1 6 5 8 7 5 5 4 5 5 6 5 5 4 6 4 5 7 3 2 5 3 5 4 5 3 5 5 4 5 3 4\n",
      " 5 5 7 4 1 2 5 8 5 8 5 3 5 8 4 3 6 3 4 3 7 5 9 2 3 2 4 7 1 5 5 3 5 5 5 5 9\n",
      " 4 5 5 5 7 5 1 1 5 3 1 7 4 3 1 4 1 4 5 8 5 4 8 2 2 2 7 5 5 5 5 7 5 6 1 6 5\n",
      " 3 5 4 5 5 4 3 5 4 4 2 7 5 4 7 4 5 5 7 5 5 4 5 5 2 4 2 5 2 3 7 4 3 1 7 5 7\n",
      " 2 4 6 1 5 3 3 4 5 5 1 5 4 5 1 5 5 4 5 6 5 5 4 2 1 4 4 7 4 3 4 2 4 2 4 5 4\n",
      " 1 4 4 5 4 5 5 4 3 5 5 3 7 1 3 4 3 9 7 2 3 7 7 1 5 4 4 5 4 8 4 0 5 7 5 5 5\n",
      " 5 4 5 5 3 5 4 3 6 4 5 5 3 2 5 5 3 4 7 5 4 2 5 4 7 5 5 1 5 5 4 5 3 3 5 7 6\n",
      " 6]\n",
      "(1000,)\n"
     ]
    }
   ],
   "source": [
    "# 聚类结果\n",
    "print(km.labels_)\n",
    "print(km.labels_.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14431, 44373, 34657, ..., 36635, 36634,     0],\n",
       "       [21121, 10903, 30402, ..., 35856, 35855,     0],\n",
       "       [37991, 44311, 21121, ..., 35698, 35697,     0],\n",
       "       ...,\n",
       "       [20726, 21121, 20721, ..., 35464, 35463,     0],\n",
       "       [17954, 24044, 19642, ..., 36350, 36349,     0],\n",
       "       [45942, 18611, 21861, ..., 36077, 36076,     0]], dtype=int64)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "order_centroids = km.cluster_centers_.argsort()[:, ::-1]\n",
    "order_centroids"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([14431, 44373, 34657, 36262, 14433, 45202, 44692, 10716, 39425,\n",
       "       30380, 31808, 36822, 20048, 17956, 17934, 47068, 40060, 13417,\n",
       "       28011, 44695, 53191,  5271, 46823, 48631, 50781, 30159, 41135,\n",
       "       27518, 19684, 14100], dtype=int64)"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 获取排名靠前的n个词的索引\n",
    "order_centroids[0, :30]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11 Cluster 0:\n",
      " 同学 老师 歪歪兔 浩浩 同学们 脑袋 联欢会 凹凸不平 电梯 教室 春天 游学团 孙欧 大家 大学 表演 的冬天 发送 扶梯 联系方式 阿甲 主讲 蝴蝶 课程 这本书 放低 知识 手工 姓名 可阳58 Cluster 1:\n",
      " 家长 分享 教育 方式 关注 事情 沟通 打印 这样 点击 给孩子 觉得 链接 可能 问题 作业帮 记得 玩具 今天 变得 耐心 需要 性格 不要 希望 有些 其实 应该 重要 喜欢60 Cluster 2:\n",
      " 爸妈 老人 家长 大人 别人 不要 容易 吃饭 喜欢 给孩子 礼貌 比较 影响 的话 你家 玩具 性格 一定 这样 夏天 长辈 不能 熊孩子 但是 不好 这些 大家 爸爸妈妈 问题 家里126 Cluster 3:\n",
      " 儿子 爸爸 可是 觉得 女儿 之后 家长 已经 妻子 教育 但是 还是 事情 特别 母亲 看到 表姐 奶奶 现在 陪伴 非常 回家 父亲 里面 也是 王猛 天天 工作 当时 最后229 Cluster 4:\n",
      " 女儿 爸爸 父亲 男孩 手机 医生 女孩 但是 家庭 母亲 看到 还是 觉得 真的 女人 她们 已经 丈夫 开始 工作 家长 发现 这些 可是 陪伴 这样 生活 可能 儿子 女孩子332 Cluster 5:\n",
      " 家长 幼儿园 学习 老师 儿童 一些 给孩子 问题 事情 行为 比如 不要 可能 需要 这种 情绪 时间 这样 或者 这些 开始 能力 容易 帮助 应该 习惯 玩具 教育 对于 不能58 Cluster 6:\n",
      " 婆婆 老公 陈女士 媳妇 儿子 母亲 李女士 老人 丈夫 女儿 老婆 婚姻 觉得 女人 孙子 男人 家庭 儿媳 照顾 儿媳妇 离婚 但是 二胎 结婚 婆媳 也是 坐月子 怀孕 医生 可是70 Cluster 7:\n",
      " 宝宝 家长 宝妈 不要 幼儿园 母乳 可能 一定 发育 但是 表现 容易 爬行 比较 大人 开始 老师 安全感 这样 这种 喜欢 事情 一些 别人 个月 爸爸妈妈 或者 情况 表扬 需要24 Cluster 8:\n",
      " 大宝 弟弟 妹妹 老大 老二 小宝 二宝 二胎 奶爸 哥哥 真诚 结扎 金龟子 李萌 养母 豆豆 姐姐 两个 上环 ta 老大的 玩伴 寄养 家庭 姑姑 照顾 爸爸妈妈 独生子女 节目 陈刚32 Cluster 9:\n",
      " 节目 央视 小歌手 乐乐 梦想 少儿频道 演唱 新年 少儿 银河 舞蹈 大家 小朋友们 之声 艺术 家帮 小伙伴 大巴 芝麻街 歌曲 播出 答题 特别节目 晚会 小朋友 张艳 红树林 制作 六一 张澄"
     ]
    }
   ],
   "source": [
    "terms = tfidf.get_feature_names()\n",
    "for i in range(k):\n",
    "    # 统计每个类的数量\n",
    "    num = np.sum(km.labels_ == i)\n",
    "    print(num, \"Cluster %d:\" % i)\n",
    "    # 根据排名靠前的n个词的索引，获取到词（这样就获取到了关键词）\n",
    "    for ind in order_centroids[i, :30]:\n",
    "        print(' %s' % terms[ind], end='')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
